// Lego_3Ddoc.h : interface of the CLego_3Ddoc class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_MRJONES_GPU_BUTTDOC_H__97EA4349_1BE8_4954_A71E_08C4F934E830__INCLUDED_)
#define AFX_MRJONES_GPU_BUTTDOC_H__97EA4349_1BE8_4954_A71E_08C4F934E830__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <CGAL/Simple_cartesian.h>
#include <cgal/HalfedgeDS_default.h>

#include "math/mathlib.h"

enum DOC_FILE_TYPE{EMPTY,MESH,IMAGE,GPU_RUNTIME};
enum MOUSE_IMAGE_INTERACTION_STATUS{IDEL,WARPING_CONTROL,
PICK_PIXEL_FOR_LOCALCAMERA_FITTING, PICK_PIXEL_FOR_SKELETON_RECON,
INPUTPOLY,
INPUTSPLINE,    // input a spline
SELECT,			// select a spline
MODIFY,			// modify the vertices of the polygon
};

enum HandleMode;

enum SUPPORT_MESH_FORMAT;
typedef FTP number_type;
typedef CGAL::Simple_cartesian<number_type> Enriched_kernel;

struct Enriched_items;

template <
class kernel, class items, 
template<class T, class I, class A> class T_HDS, 
class A 
> class Enriched_polyhedron;
typedef Enriched_polyhedron<Enriched_kernel, Enriched_items, CGAL::HalfedgeDS_default, CGAL_ALLOCATOR(int)> Mesh;

template<class _poly, class _kernel> class CGeodesic_estimator;
typedef CGeodesic_estimator<Mesh, Enriched_kernel> GeodesicEstimator;

template<class _poly, class _kernel> class CSkeleton; 
typedef CSkeleton<Mesh,Enriched_kernel> Skeleton;

template<class _poly, class _kernel> class CSpacePartitioner;
typedef CSpacePartitioner<Mesh, Enriched_kernel> SpacePartitioner;

template<class _poly, class _kernel> class COctreePartitioner;
typedef COctreePartitioner<Mesh, Enriched_kernel> OctreePartitioner;

template<class _poly, class _kernel> class CMeshVoxelizer;
typedef CMeshVoxelizer<Mesh, Enriched_kernel> MeshVoxelizer;

class CLego_3Dview;
class CLego_3Dapp;
class Image_Resize;
class CWarp;
class CPolygon;
class CMultiPolygon;
class CSelectedPolygon;
template<class T> class CTrackBall;

class CLego_3Ddoc : public CDocument
{
protected: // create from serialization only
	CLego_3Ddoc();
	virtual ~CLego_3Ddoc();
	DECLARE_DYNCREATE(CLego_3Ddoc)
//data contents
	//for frame
public:
	CLego_3Dapp *m_pApp;
	CLego_3Dview *m_pView;
	bool m_bClosing;
private:
	CString img_strfilterload,img_strfilterwrite, mesh_strfilterload, mesh_strfilterwrite;
	CString	 m_FilePath, m_Filetype;
	bool m_bModified;
	DOC_FILE_TYPE m_DocType;
public:
	//for mouse
	MOUSE_IMAGE_INTERACTION_STATUS  m_ImageMouseCtrl;
	//for image
	Image_Resize  *m_pImage;
	CWarp *pWarp;
	//for mesh
	Mesh *m_pMesh;
	std::vector<Mesh*>		m_MeshPool; 
	float m_UniScale;
	//geodesic
	GeodesicEstimator	*m_pGeoEstimator;
	//skeleton
	Skeleton *m_pSkeleton;
	std::vector<Skeleton*>	m_SkelPool;
	//space partitioning
	SpacePartitioner	*m_pSpacePar;
	int m_SpaceParMaxDepth;	
	//side img
	Image_Resize *pSideImg;
	CLego_3Ddoc *pSideDoc; 
	//for spline on image
	CMultiPolygon		*m_MultiPolygons;	// all the polygons
	CSelectedPolygon	*m_SelectedPolygons;	// the selected polygons in SELECT op
	CPolygon			*m_pNewPolygon;		// new input polygon, current input polygon in INPUT* ops
	int					m_nSelectedPoly;	// the selected polygon in MODIFY op
	int					m_nSelectedVertex;	// the selected vertex in MODIFY op
	HandleMode			m_nHandleMode;		// the handle mode in SELECT and MODIFY ops, for different handles
	//for image warping using triangulation.
	Mesh *m_pWarpMesh;	

// Operations	
	//for frame
public:
	virtual void Serialize(CArchive& ar);
	virtual BOOL OnNewDocument();
	BOOL OnSaveDocument(LPCTSTR lpszPathName);
	virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif
	BOOL IsFileModified();
	CString GetFileName();
	void StatusMessage(char* fmt, ... );
	const Image_Resize* GetImage(void) const;  //Image
	BOOL LoadFromImageFile();
	bool IS_CGAL_Support_Reading(SUPPORT_MESH_FORMAT smf); //mesh
	bool IS_CGAL_Support_Wrting(SUPPORT_MESH_FORMAT smf);
	bool LoadMesh(const CString &sMeshPathName, Mesh *&pMesh,double given_scalef=0.0, bool bRenderNow=true);
	BOOL SaveModel(LPCTSTR lpszPathName, Mesh *pMesh);
	void UpdateMeshProperties(Mesh *pMesh, bool update_component=false, bool update_boundary=false);
	void UpdateImageProperties(Image_Resize *pImage, CPoint MousePos=CPoint(0,0) );
	void LoadSideImage(CString path="");	
	void LoadSkeleton(CString sFilename, Skeleton *&pSkt,Mesh *pMesh=NULL,bool bRenderNow=true,double given_scalef=0.0, bool bUnitToMeshCenter=true,bool bLoadBoneWeights=false);
	void LoadBoneWeight(CString sFilename,Skeleton *pSkt)/*load Bone Weights for the corresponding skeleton */;
	void ResetMeshProperties();
	void AddNewPolygon( bool closed );//spline on image
	void AddNewSpline( bool closed );
	void ClearSelectedPolys();
	void DeleteSelectedPolygons();
	void SelectAllSpline();	
	void ReverseVertexOrder();
//message map
protected:
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnFileSave();
	afx_msg void OnCloseDocument();
	afx_msg void OnLoadAnotherMesh();
	afx_msg void OnBatchLoadMesh();
	afx_msg void OnPick_2D_and_3D_Point();
	afx_msg void OnUpdatePick_2D_and_3D_Point(CCmdUI *pCmdUI);
	afx_msg void OnLoadPickedImagePoints();
	afx_msg void OnSavePickedImagePoints();
	afx_msg void OnViewLoadCam();
	afx_msg	void OnViewSaveCam();
	afx_msg	void OnViewSetCam();
	afx_msg	void OnSaveMesh2DProjection();
	afx_msg void OnImageTestResizing();  	//image
	afx_msg void OnImageLoadsalienceMap();
	afx_msg void OnImageResizeToSpecifiedSize();
	afx_msg void OnImageWarping();
	afx_msg void OnImageWarpOptimizeOnce();
	afx_msg void OnSaveWarpContrlPtsPair();
	afx_msg void OnLoadWarpContrlPtsPair();
	afx_msg void OnUpdateImageTestResizing(CCmdUI *pCmdUI);
	afx_msg void OnUpdateImageLoadsalienceMap(CCmdUI *pCmdUI);
	afx_msg void OnUpdateImageResizeSpecifiedSize(CCmdUI *pCmdUI);
	afx_msg void OnUpdateImageWarping(CCmdUI *pCmdUI);
	afx_msg void OnUpdateImageWarpOptimizeOnce(CCmdUI *pCmdUI);
	afx_msg void OnComputeGeodesicMatrix();		//geodesic
	afx_msg void OnSaveGeodesicMatrix();
	afx_msg void OnLoadGeodesicMatrix();
	afx_msg void OnPickGeodesicPath();
	afx_msg void OnBatchProduceGDM();
	afx_msg void OnOpenSideImage();				//Model driven image warping
	afx_msg void OnUpdateOpenSideImage(CCmdUI *pCmdUI);
	afx_msg void OnLoadSkeleton();//Skeleton
	afx_msg void OnShowSkeleton();
	afx_msg void OnShowSkeletonJointsName();
	afx_msg void OnShowSkeletonBonesName();
	afx_msg void OnLoadBoneWeights();
	afx_msg void OnLoadSegInfo();	
	afx_msg void OnBatchLoadSkeleton();
	afx_msg void OnSaveSkeleton();
	afx_msg void OnBatchSaveSkeleton();
	afx_msg void OnUpdateShowSkeleton(CCmdUI *pCmdUI);
	afx_msg void OnUpdateShowSkeletonJointsName( CCmdUI *pCmdUI );
	afx_msg void OnUpdateShowSkeletonBonesName(CCmdUI *pCmdUI);
	afx_msg void OnUpdateShowSegBodyPartByBW( CCmdUI *pCmdUI );
	afx_msg void On2DSplineSetting();	//spline on images
	afx_msg void OnVoxelizationNew();
	afx_msg void OnUpdateVoxelizationNew(CCmdUI *pCmdUI);
	afx_msg void OnOctreeNew();
	afx_msg void OnUpdateOctreeNew(CCmdUI *pCmdUI);
	afx_msg void OnOctreeLoad();
	afx_msg void OnOctreeStore();
	afx_msg void OnCubeAnalyzer();
	afx_msg void OnMeshRegulateInit();
	afx_msg void OnMeshRegulateRunOnce();
	afx_msg void OnMeshRegulateShowTempV();
	afx_msg void OnMeshRegulatePrintDeviation();
};

inline CString CLego_3Ddoc::GetFileName()
{		
	if(m_FilePath!="")	return m_FilePath;
	return "";
}

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MRJONES_GPU_BUTTDOC_H__97EA4349_1BE8_4954_A71E_08C4F934E830__INCLUDED_)
